package com.laboratory.servicecustomer.controller;

import com.Laboratory.pojo.user;
import com.Laboratory.service.userService;
import com.laboratory.servicecustomer.constant.constantArgs;
import com.laboratory.servicecustomer.realm.MyRealm;
import com.laboratory.servicecustomer.utilPojo.LoginPojo;
import com.laboratory.servicecustomer.utilPojo.comm;
import com.laboratory.servicecustomer.utilPojo.updatePasswordPojo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import org.apache.shiro.subject.Subject;

import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author acok
 * @description:user实体类控制层
 * @Date 2022/12/5 10:03
 * @Version 1.0
 */

@Controller
@RequestMapping("/user")
public class userController {

    @Autowired
    private MyRealm myRealm;
    @DubboReference(interfaceClass = userService.class,version = "1.0.0")
    private userService userService;
    /**
           * @return: 响应结果
           * @param: username（用户名）、password（密码）、rememberMe(记住我)
           * @description:登录api
           * @Author: Acok
           * @mbggenerated 2022/12/6
           */

    @PostMapping("/login")
    @ResponseBody
    public Object getUserToLogin(@RequestBody LoginPojo loginPojo){
        comm comm=new comm();
        Subject subject= SecurityUtils.getSubject();
        AuthenticationToken token=new UsernamePasswordToken(
                loginPojo.getUsername(),
                loginPojo.getPassword());
        try {
            subject.login(token);
            comm.setCode(constantArgs.COMMUNITY_SUCCESS_CODE);
            comm.setMessage(constantArgs.COMMUNITY_SUCCESS_MESSAGE);
            return comm;
        }catch (AuthenticationException e){
            e.printStackTrace();
            comm.setCode(constantArgs.COMMUNITY_FAIL_CODE);
            comm.setMessage(constantArgs.COMMUNITY_FAIL_MESSAGE);
            return comm;
        }

    }
      /**
           * @return:响应结果
           * @param:username（用户名）
           * @description:根据用户名获取当前用户相关信息
           * @Author: Acok
           * @mbggenerated 2022/12/6
           */

    @PostMapping("/getUserByName")
    @ResponseBody
    public Object getUserByName(String username){
        comm comm=new comm();
        try{
            user user = userService.getUserDetailByName(username);
            comm.setCode(constantArgs.COMMUNITY_SUCCESS_CODE);
            comm.setMessage(constantArgs.COMMUNITY_SUCCESS_MESSAGE);
            comm.setOther(user);
        }catch (Exception e){
            comm.setCode(constantArgs.COMMUNITY_FAIL_CODE);
            comm.setMessage(constantArgs.COMMUNITY_FAIL_MESSAGE);
            e.printStackTrace();
        }
        return comm;
    }

    @GetMapping("/getUserNameList")
    @ResponseBody
    public Object getUserNameList(){
        comm comm=new comm();
        try {
            List<String> accountList = userService.getAccountList();
            comm.setCode(constantArgs.COMMUNITY_SUCCESS_CODE);
            comm.setMessage(constantArgs.COMMUNITY_SUCCESS_MESSAGE);
            comm.setOther(accountList);
        }catch (Exception e){
            e.printStackTrace();
            comm.setCode(constantArgs.COMMUNITY_FAIL_CODE);
            comm.setMessage(constantArgs.COMMUNITY_FAIL_MESSAGE);
        }
        return comm;
    }

    @PostMapping("/createUser")
    @ResponseBody
    public Object createUser(
            @RequestParam("id") String id,
            @RequestParam("account") String account,
            @RequestParam("password") String password,
            @RequestParam("telephone") String telephone,
            @RequestParam("identity") String identity,
            @RequestParam("createtime") String createtime,
            @RequestParam("email") String email,
            @RequestParam("salt") String salt
    ){
        comm comm = new comm();
        user user=new user();
        user.setId(id);
        user.setAccount(account);
        user.setPassword(password);
        user.setTelephone(telephone);
        user.setIdentity(identity);
        user.setCreatetime(createtime);
        user.setEmail(email);
        user.setSalt(salt);
        try {
            if (userService.createUser(user)>0) {
                comm.setCode(constantArgs.COMMUNITY_SUCCESS_CODE);
                comm.setMessage(constantArgs.COMMUNITY_SUCCESS_MESSAGE);
            }else {
                comm.setCode(constantArgs.COMMUNITY_FAIL_CODE);
                comm.setMessage(constantArgs.COMMUNITY_FAIL_MESSAGE);
            }
        }catch (Exception e){
            e.printStackTrace();
            comm.setCode(constantArgs.COMMUNITY_FAIL_CODE);
            comm.setMessage(constantArgs.COMMUNITY_FAIL_MESSAGE);
        }
        return  comm;
    }

    @RequiresRoles(value = {"users","admin","Root"},logical = Logical.OR)
    @RequiresPermissions(value = {"users:home","admin:home","Root:highest"},logical = Logical.OR)
    @PostMapping("/updateUserMessage")
    @ResponseBody
    public Object updateUserMessage(@RequestBody user user){
        comm comm=new comm();
        try {
            if(userService.updateUserMessage(user)>0){
                comm.setCode(constantArgs.COMMUNITY_SUCCESS_CODE);
                comm.setMessage(constantArgs.COMMUNITY_SUCCESS_MESSAGE);
            }else {
                comm.setCode(constantArgs.COMMUNITY_FAIL_CODE);
                comm.setMessage(constantArgs.COMMUNITY_FAIL_MESSAGE);
            }
        }catch (Exception e){
            e.printStackTrace();
            comm.setCode(constantArgs.COMMUNITY_FAIL_CODE);
            comm.setMessage(constantArgs.COMMUNITY_FAIL_MESSAGE);
        }
        return comm;
    }

    @RequiresRoles(value = {"users","admin","Root"},logical = Logical.OR)
    @RequiresPermissions(value = {"users:home","admin:home","Root:highest"},logical = Logical.OR)
    @PostMapping("/updatePassword")
    @ResponseBody
    public Object updatePassword(@RequestBody updatePasswordPojo updatePasswordPojo){
        comm comm=new comm();
        try{
            if (userService.beforeUpdateUserPassword(updatePasswordPojo.getAccount(),
                    updatePasswordPojo.getOldPassword(),
                    updatePasswordPojo.getNewPassword())>0){
                comm.setCode(constantArgs.COMMUNITY_SUCCESS_CODE);
                comm.setMessage(constantArgs.COMMUNITY_SUCCESS_MESSAGE);
            }
        }catch (Exception e){
            e.printStackTrace();
            comm.setCode(constantArgs.COMMUNITY_FAIL_CODE);
            comm.setMessage(constantArgs.COMMUNITY_FAIL_MESSAGE);
        }
        return comm;
    }

    @RequiresRoles(value = {"admin","Root"},logical = Logical.OR)
    @RequiresPermissions(value = {"admin:purviewManage","Root:highest"},logical = Logical.OR)
    @GetMapping("/getUserMessageList")
    @ResponseBody
    public Object getUserMessageList(){
        comm comm=new comm();
        try {
            Map<String,Object> resultMap=new HashMap<>();
            List<user> userList = userService.getUserList();
            resultMap.put("userList",userList);
            List<Map<String, Object>> roleList = userService.getRoleList();
            resultMap.put("roleList",roleList);
            List<Map<String, Object>> authorityList = userService.getAuthorityList();
            resultMap.put("authorityList",authorityList);
            comm.setCode(constantArgs.COMMUNITY_SUCCESS_CODE);
            comm.setMessage(constantArgs.COMMUNITY_SUCCESS_MESSAGE);
            comm.setOther(resultMap);
        }catch (Exception e){
            e.printStackTrace();
            comm.setCode(constantArgs.COMMUNITY_FAIL_CODE);
            comm.setMessage(constantArgs.COMMUNITY_FAIL_MESSAGE);
        }
        return comm;
    }

    @RequiresRoles(value = {"Root"})
    @RequiresPermissions(value = {"Root:highest"})
    @PostMapping("/updateUserAccountState")
    @ResponseBody
    public Object updateUserAccountState(
            @RequestParam("id")String id,
            @RequestParam("state")String state,
            @RequestParam("type")String type
    ){
        comm comm=new comm();
        try{
            if(userService.updateAccountState(id, state, type)>0){
                DefaultWebSecurityManager securityManager= (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
                MyRealm realm = (MyRealm)securityManager.getRealms().iterator().next();
                realm.clearAllPermissionCache();
                comm.setCode(constantArgs.COMMUNITY_SUCCESS_CODE);
                comm.setMessage(constantArgs.COMMUNITY_SUCCESS_MESSAGE);
            }else {
                comm.setCode(constantArgs.COMMUNITY_FAIL_CODE);
                comm.setMessage(constantArgs.COMMUNITY_FAIL_MESSAGE);
            }
        }catch (Exception e){
            e.printStackTrace();
            comm.setCode(constantArgs.COMMUNITY_FAIL_CODE);
            comm.setMessage(constantArgs.COMMUNITY_FAIL_MESSAGE);
        }
        return comm;
    }

    @RequiresRoles(value = {"Root"})
    @RequiresPermissions(value = {"Root:highest"})
    @PostMapping("/updateUserRole")
    @ResponseBody
    public Object updateUserRole(
            @RequestParam("id")String id,
            @RequestParam("role")String role
    ){
        comm comm=new comm();
        try {
            if (userService.updateUserRole(id, role)>0) {
                DefaultWebSecurityManager securityManager= (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
                MyRealm realm = (MyRealm)securityManager.getRealms().iterator().next();
                realm.clearAllPermissionCache();
                comm.setCode(constantArgs.COMMUNITY_SUCCESS_CODE);
                comm.setMessage(constantArgs.COMMUNITY_SUCCESS_MESSAGE);
            }else {
                comm.setCode(constantArgs.COMMUNITY_FAIL_CODE);
                comm.setMessage(constantArgs.COMMUNITY_FAIL_MESSAGE);
            }
        }catch (Exception e){
            e.printStackTrace();
            comm.setCode(constantArgs.COMMUNITY_FAIL_CODE);
            comm.setMessage(constantArgs.COMMUNITY_FAIL_MESSAGE);
        }
        return comm;
    }

    @RequiresRoles(value = {"Root"})
    @RequiresPermissions(value = {"Root:highest"})
    @PostMapping("/deleteUserById")
    @ResponseBody
    public Object deleteUserById(@RequestParam("id") String id,
                                 @RequestParam("fromAccount")String fromAccount,
                                 @RequestParam("passwordCord")String passwordCode,
                                 @RequestParam("targetAccount")String targetAccount){
        comm comm=new comm();
        try {
            if(userService.deleteUserById(id,fromAccount,passwordCode,targetAccount)>0){
                comm.setCode(constantArgs.COMMUNITY_SUCCESS_CODE);
                comm.setMessage(constantArgs.COMMUNITY_SUCCESS_MESSAGE);
            }else {
                comm.setCode(constantArgs.COMMUNITY_FAIL_CODE);
                comm.setMessage(constantArgs.COMMUNITY_FAIL_MESSAGE);
            }
        }catch (Exception e){
            e.printStackTrace();
            comm.setCode(constantArgs.COMMUNITY_FAIL_CODE);
            comm.setMessage(constantArgs.COMMUNITY_FAIL_MESSAGE);
        }
        return comm;
    }
}
